Skip to content

Bug fixes 4 6 2026#4

Merged
cwdaniel merged 2 commits into
mainfrom
bug-fixes-4-6-2026
Apr 9, 2026
Merged

Bug fixes 4 6 2026#4
cwdaniel merged 2 commits into
mainfrom
bug-fixes-4-6-2026

Conversation

@cwdaniel

@cwdaniel cwdaniel commented Apr 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fix wind flow freezing/janking during map pan and zoom
  • Fix NEXRAD 250m tiles disappearing after ~30 minutes post-deployment

Closes #1
Closes #2

Changes

  • Wind rendering (public/index.html, landing/index.html): Replace 375K per-frame latLngToContainerPoint calls with inline
    Mercator math (1 Leaflet call + multiply/add per trail point), batch canvas stroke() calls by color (15K → ~20), remove
    pause/resume mechanism so wind flows continuously during interaction
  • NEXRAD ingester (src/nexrad/main.ts): Refresh Redis scan TTL unconditionally at the start of each poll cycle, before any S3
    work — prevents scans from expiring through stale data, S3 errors, date rollover, or network failures
  • Scan provider (src/server/nexrad-scan-provider.ts): Add try/catch around Redis reads in getScan so connection blips don't
    crash tile requests

Testing

  • npx tsc --noEmit passes
  • Docker builds successfully
  • Tested locally with docker compose up
  • Verified in browser at localhost:8600
  • Wind flow remains smooth during pan/zoom on both landing page and /app
  • All 137 unit tests pass

Screenshots

N/A — no visual design changes, only performance and reliability fixes.

cwdaniel added 2 commits April 8, 2026 23:06
…n on map

 Root Cause

  fetchLatest() had 5 early-return paths that didn't refresh the Redis TTL for existing scans:

  1. S3 listing returns HTTP error
  2. S3 listing has no contents (happens at UTC date rollover)
  3. No V06/V08 volume files found
  4. File timestamp parse fails
  5. Station data >30 min old (stale) ← the most common trigger

  Since SCAN_TTL and MAX_AGE_MS are both 30 minutes, once a station's S3 data ages past 30 minutes the TTL stops being refreshed, and
  the scan expires from Redis within the remaining TTL window. At z8+ there's no MRMS fallback (tilers produce z2-7 only), so expired
  scans = transparent tiles.

  The previous fix (commit 4e01caf) increased TTL from 10 to 30 minutes — this delayed the symptom from ~10 min to ~30 min but didn't
  address the root cause.

  Changes

  src/nexrad/main.ts — Unconditionally refresh TTL for previously-ingested stations at the top of fetchLatest(), before any S3 work.
  This single line covers all failure paths (stale data, S3 errors, network issues, date rollover). The .catch(() => {}) prevents Redis
   connection errors from blocking the fetch attempt.

  src/server/nexrad-scan-provider.ts — Wrap readScanFromRedis in try/catch so Redis connection blips don't crash tile requests
  (defense-in-depth).
 Two changes across both public/index.html (the app) and landing/index.html (the homepage):

  1. Replaced 375K Leaflet calls per frame with inline math

  The old code called map.latLngToContainerPoint() for every trail point of every particle — 15,000 particles × 25 trail points =
  375,000 calls per frame. Each call created 3 Leaflet objects and did full Mercator projection math, generating ~1.1M garbage objects
  per frame for the GC.

  The fix stores trails in normalized Mercator coordinates (nx = lon/360 + 0.5, ny via a single log/tan), extracts the map transform
  once per frame with a single Leaflet call, then converts all trail points with just x = nx * scale + ox (multiply + add). Same visual
   result, ~100x less work.

  2. Batched canvas draw calls by color

  The old code did a separate beginPath() / stroke() for each particle — 15,000 stroke() calls per frame. Each stroke() triggers
  rasterization.

  The fix bins particles by their color index, then draws each color group with a single beginPath() / stroke(). Reduces draw calls
  from ~15K to ~20.

  3. Removed the pause/resume mechanism

  The old code froze the animation on movestart/zoomstart and resumed on moveend/zoomend. This caused the visible "freeze then
  recalculate" behavior. With the inline math being fast enough (~2-4ms per frame vs the old ~50ms), the animation now runs
  continuously during pan/zoom with no pause needed.
@cwdaniel cwdaniel merged commit fa11e16 into main Apr 9, 2026
@cwdaniel cwdaniel deleted the bug-fixes-4-6-2026 branch April 9, 2026 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] NexRad radars seem to disconnect after an hour and are not shown on map [Bug] Zoom levels affect wind data

1 participant